import { defineComponent, h, render, VNode, ref, watch } from 'vue';
import { ProgressElementInterface } from './ProgressElementInterface';

/**
 * VueProgress组件配置选项接口
 * 用于定义VueProgress组件的初始化参数
 */
export interface VueProgressOptions {
    /**
     * 进度条显示的文本内容
     * @default ''
     */
    text?: string;

    /**
     * 进度文本模板，支持{text}和{progress}占位符
     * {text} - 替换为text属性的值
     * {progress} - 替换为当前进度百分比
     * @default '{progress}'
     */
    textTemplate?: string;

    /**
     * 进度条颜色
     * @default '#a0cfff'
     */
    color?: string;

    /**
     * 进度条完成时的颜色
     * @default '#67C23A'
     */
    completeColor?: string;

    /**
     * 进度条文本颜色
     * @default '#337ecc'
     */
    textColor?: string;

    /**
     * 进度条完成时的文本颜色
     * @default 'white'
     */
    completeTextColor?: string;
}

/**
 * Vue类型进度条组件
 * 实现ProgressElementInterface接口，提供基于Vue的进度条功能
 * 特点：轻量级内联进度显示，支持文本模板和渐变色背景
 * @example
 * ```typescript
 * const progress = new VueProgress({
 *   text: '下载中',
 *   textTemplate: '{text} - {progress}%'
 * });
 * container.appendChild(progress.getElement());
 * progress.updateState(35); // 更新为35%进度
 * ```
 */
export class VueProgress implements ProgressElementInterface {
    /**
     * Vue组件VNode
     */
    private __vnode: VNode | null = null;

    /**
     * 进度条DOM容器
     */
    private __container: HTMLDivElement;

    /**
     * 进度条配置选项
     */
    private __options: VueProgressOptions;

    /**
     * 当前进度百分比
     * @default 0
     */
    private __progress: number = 0;

    /**
     * 进度条显示文本
     */
    private __text: string = '';

    /**
     * 进度文本模板字符串
     * @default '{progress}'
     */
    private __textTemplate: string = '{progress}';

    /**
     * VueProgress构造函数
     * 初始化进度条元素并应用配置选项
     * @param {VueProgressOptions} [options] - 进度条配置选项
     */
    constructor(options?: VueProgressOptions) {
        // 应用配置选项
        this.__options = options || {};
        this.__textTemplate = this.__options.textTemplate || this.__textTemplate;
        this.__text = this.__options.text || this.__text;

        // 创建容器元素
        this.__container = document.createElement('div');

        // 初始化进度条
        this.createElement();
    }

    // 静态组件定义，避免重复创建
    private static ProgressComponent = defineComponent({
        props: ['options', 'progress', 'params'],
        setup(props) {
            // 使用响应式引用包装进度值
            const progressRef = ref(props.progress);
            const paramsRef = ref(props.params || {});

            // 当外部进度变化时更新响应式引用
            watch(() => props.progress, (newVal) => {
                progressRef.value = newVal;
            });

            // 当外部参数变化时更新响应式引用
            watch(() => props.params, (newVal) => {
                paramsRef.value = newVal || {};
            });

            return {
                progressRef,
                paramsRef,
                options: props.options
            };
        },
        render() {
            const { progressRef, options } = this;
            const progressValue = progressRef;

            // 确定进度条颜色
            const color = progressValue < 100
                ? options.color || '#a0cfff'
                : options.completeColor || '#67C23A';

            // 确定文本颜色
            const textColor = progressValue < 100
                ? options.textColor || '#337ecc'
                : options.completeTextColor || 'white';

            // 格式化进度文本
            const textTemplate = options.textTemplate || '{progress}';
            const text = options.text || '';
            let displayText = textTemplate.replace(/{text}/g, text).replace(/{progress}/g, progressValue.toString());

            // 替换自定义占位符
            if (this.paramsRef) {
                Object.entries(this.paramsRef).forEach(([key, value]) => {
                    const placeholder = `{${key}}`;
                    if (displayText.includes(placeholder)) {
                        displayText = displayText.replace(new RegExp(placeholder, 'g'), String(value));
                    }
                });
            }

            // 渲染自定义Vue进度条组件
            return h('span', {
                style: {
                    display: 'inline-block',
                    cursor: 'pointer',
                    background: `linear-gradient(to right, ${color} ${progressValue}%, transparent ${progressValue}%)`,
                    transition: 'background 0.3s ease',
                    position: 'relative',
                    overflow: 'visible',
                    color: textColor,
                    WebkitUserSelect: 'none',
                    userSelect: 'none',
                    padding: '2px 6px',
                    borderRadius: '4px'
                }
            }, displayText);
        }
    });

    /**
     * 创建进度条元素
     * @returns HTMLDivElement 进度条容器元素
     */
    createElement(): HTMLDivElement {
        // 创建VNode，传递选项和进度值作为props
        this.__vnode = h(VueProgress.ProgressComponent, {
            options: this.__options,
            progress: this.__progress,
            params: {}
        });

        // 渲染到容器
        render(this.__vnode, this.__container);

        return this.__container;
    }

    /**
     * 更新进度条状态
     * @param progress 当前进度百分比 (0-100)
     * @param params 可选的自定义参数对象，用于模板变量替换
     */
    updateState(progress: number, params?: Record<string, any>): void {
        const progressValue = Math.min(Math.max(progress, 0), 100);
        this.__progress = progressValue;

        // 利用Vue的响应式系统更新进度
        if (this.__vnode && this.__vnode.component) {
            // 更新组件的props，Vue会自动触发重新渲染
            this.__vnode.component.props.progress = progressValue;
            this.__vnode.component.props.params = params;
        }
    }

    /**
     * 获取进度条元素
     * @returns HTMLDivElement 进度条容器元素
     */
    getElement(): HTMLDivElement {
        return this.__container;
    }
}